package com.itkaien.AopAspectjXml;

import com.itkaien.AopAspectjXml.advice.Myadvice;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//@Component
public class MockBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {

    private AnnotationConfigApplicationContext context;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {




        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        System.out.println(bean.getClass().getPackage().getName());
        if (bean.getClass().getPackage().getName().equals("com.itkaien.Aop.impl")) {
            Object o = Proxy.newProxyInstance(bean.getClass().getClassLoader(),
                    bean.getClass().getInterfaces(),
                    (Object proxy, Method method, Object[] args) -> {
                        Myadvice bean1 = context.getBean(Myadvice.class);
                        //前置通知
                        bean1.before();
                        //执行方法
                        Object invoke = method.invoke(bean, args);
                        //后置通知
                        bean1.after();
                        return invoke;
                    });
            return o;
        }
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = (AnnotationConfigApplicationContext) applicationContext;
    }
}
